#include "wav_parser.h"

char *WavParser::WAV_P_FmtString(uint16_t fmt)
{
    switch (fmt) {
    case WAV_FMT_PCM:
        return "PCM";
        break;
    case WAV_FMT_IEEE_FLOAT:
        return "IEEE FLOAT";
        break;
    case WAV_FMT_DOLBY_AC3_SPDIF:
        return "DOLBY AC3 SPDIF";
        break;
    case WAV_FMT_EXTENSIBLE:
        return "EXTENSIBLE";
        break;
    default:
        break;
    }

    return "NON Support Fmt";
}

void WavParser::WAV_P_PrintHeader(WAVContainer_t *container)
{
    printf("+++++++++++++++++++++++++++\n");
    printf("\n");

    printf("File Magic:         [%c%c%c%c]\n",
           (char)(container->header.magic),
           (char)(container->header.magic>>8),
           (char)(container->header.magic>>16),
           (char)(container->header.magic>>24));
    printf("File Length:        [%d]\n", container->header.length);
    printf("File Type:          [%c%c%c%c]\n",
           (char)(container->header.type),
           (char)(container->header.type>>8),
           (char)(container->header.type>>16),
           (char)(container->header.type>>24));
    printf("\n");
    printf("Fmt Magic:          [%c%c%c%c]\n",
           (char)(container->format.magic),
           (char)(container->format.magic>>8),
           (char)(container->format.magic>>16),
           (char)(container->format.magic>>24));
    printf("Fmt Size:           [%d]\n", container->format.fmt_size);
    printf("Fmt Format:         [%s]\n", WAV_P_FmtString(container->format.format));
    printf("Fmt Channels:       [%d]\n", container->format.channels);
    printf("Fmt Sample_rate:    [%d](HZ)\n", container->format.sample_rate);
    printf("Fmt Bytes_p_second: [%d]\n", container->format.bytes_p_second);
    printf("Fmt Blocks_align:   [%d]\n", container->format.blocks_align);
    printf("Fmt Sample_length:  [%d]\n", container->format.sample_length);

    printf("\n");

    printf("Chunk Type:         [%c%c%c%c]\n",
           (char)(container->chunk.type),
           (char)(container->chunk.type>>8),
           (char)(container->chunk.type>>16),
           (char)(container->chunk.type>>24));
    printf("Chunk Length: [%d]\n", container->chunk.length);

    printf("\n");
    printf("++++++++++++++++++++++++++++++++++++++\n");
}

int WavParser::WAV_P_CheckValid(WAVContainer_t *container)
{
    if (container->header.magic != WAV_RIFF ||
            container->header.type != WAV_WAVE ||
            container->format.magic != WAV_FMT ||
            container->format.fmt_size != LE_INT(16) ||
            (container->format.channels != LE_SHORT(1) && container->format.channels != LE_SHORT(2))
            || container->chunk.type != WAV_DATA) {
        fprintf(stderr, "non standard wav file.\n");
        return -1;
    }

    return 0;
}

WavParser::WavParser(QObject *parent) :
    QObject(parent)
{

}

int WavParser::WAV_ReadHeader(int fd, WAVContainer_t *container)
{
    assert((fd >=0) && container);

    if (read(fd,&container->header,sizeof(container->header))!=sizeof(container->header)
            ||read(fd,&container->format,sizeof(container->format))!=sizeof(container->format)
            ||read(fd,&container->chunk,sizeof(container->chunk))!=sizeof(container->chunk)){

        fprintf(stderr, "Error WAV_ReadHeader\n");
        return -1;
    }

    if (WAV_P_CheckValid(container) < 0)
        return -1;

#ifdef WAV_PRINT_MSG
    WAV_P_PrintHeader(container);
#endif

    return 0;
}

int WavParser::WAV_WriteHeader(int fd, WAVContainer_t *container)
{
    assert((fd >=0) && container);

    if (WAV_P_CheckValid(container) < 0)
        return -1;

    if (write(fd,&container->header,sizeof(container->header))!=sizeof(container->header)
            ||write(fd,&container->format,sizeof(container->format))!=sizeof(container->format)
            ||write(fd,&container->chunk,sizeof(container->chunk))!=sizeof(container->chunk)) {
        fprintf(stderr, "Error WAV_WriteHeader\n");
        return -1;
    }

#ifdef WAV_PRINT_MSG
    WAV_P_PrintHeader(container);
#endif

    return 0;
}
